package com.js.data.system.security.service;

import com.js.data.common.constant.CommonConstant;
import com.js.data.common.constant.SymbolConstant;
import com.js.data.common.dto.SecurityUserDTO;
import com.js.data.common.dto.UserMenuVO;
import com.js.data.common.exception.ApiException;
import com.js.data.common.exception.EntityNotFoundException;
import com.js.data.system.dto.JwtUserDTO;
import com.js.data.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author Zheng Jie
 * @date 2018-11-22
 */
@Slf4j
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Resource
    private UserService userService;

    @Resource
    private UserDeptService userDeptService;

    @Resource
    private RoleService roleService;

    @Resource
    private MenuService menuService;

    @Resource
    private UserCacheManager userCacheManager;


    @Resource
    private DeptService deptService;

    @Override
    public JwtUserDTO loadUserByUsername(String username) throws UsernameNotFoundException {
        // 登录情况重新走一遍
        JwtUserDTO jwtUserDto = null;
        if (!username.contains(CommonConstant.LOGIN_EXT_STR)) {
            jwtUserDto = userCacheManager.getUserCache(username);
        } else {
            username = username.replace(CommonConstant.LOGIN_EXT_STR, SymbolConstant.BLANK);
        }
        if (jwtUserDto == null) {
            SecurityUserDTO user;
            try {
                user = userService.getUserByUserName(username);
            } catch (EntityNotFoundException e) {
                // SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException
                throw new UsernameNotFoundException("", e);
            }
            if (user == null) {
                throw new UsernameNotFoundException("");
            } else {
                if (!user.isEnabled()) {
                    throw new ApiException("账号未激活！");
                }
            }
            List<Long> dataScopeIds = new ArrayList<>();
            // 管理员
            if (user.isAdmin()) {
                List<GrantedAuthority> authorities = new ArrayList<>();
                SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(CommonConstant.ROLE_ADMIN_STR);
                authorities.add(simpleGrantedAuthority);
                // 获取所有菜单
                Set<UserMenuVO> userMenuVOS = menuService.userMenu();
                user.setUserMenu(userMenuVOS);
                dataScopeIds.addAll(deptService.listAllDept());
                jwtUserDto = new JwtUserDTO(user, dataScopeIds, authorities);
            } else {
                userDeptService.getUserPermDeptIds(user.getId(), user.getDeptId(), user.getPermType(), dataScopeIds);
                jwtUserDto = new JwtUserDTO(user, dataScopeIds, roleService.getGrantedAuthorities(user));
            }

            // 添加缓存数据
            userCacheManager.addUserCache(username, jwtUserDto);
        }
        return jwtUserDto;

    }
}
